package com.hotec.PROJECT_NAME.modules.sys.service;

import cn.hutool.core.util.ObjectUtil;
import com.gemcap.framework.data.utils.UtilsDataReflection;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hotec.PROJECT_NAME.component.basic.BaseService;
import com.hotec.PROJECT_NAME.component.basic.ConstantKey;
import com.hotec.PROJECT_NAME.component.exception.exc.BizException;
import com.hotec.PROJECT_NAME.modules.sys.entity.SysResource;
import com.hotec.PROJECT_NAME.modules.sys.entity.SysRole;
import com.hotec.PROJECT_NAME.modules.sys.entity.SysRoleAccount;
import com.hotec.PROJECT_NAME.modules.sys.entity.SysRoleResource;
import com.hotec.PROJECT_NAME.modules.sys.mapper.SysRoleMapper;
import com.hotec.PROJECT_NAME.utils.UtilsTreeBuilder;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author llb
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysRoleService extends BaseService<SysRole, SysRoleMapper> {
    @Autowired
    SysRoleAccountService roleAccountService;
    @Autowired
    SysRoleResourceService roleResourceService;
    @Autowired
    SysResourceService sysResourceService;

    @Override
    public List<SysRole> queryAll() {
        return new UtilsTreeBuilder(SysRole.class).listToTree(this.queryAllWithOutTree().stream().distinct().collect(Collectors.toList()));
    }

    public List<SysRole> queryAllWithOutTree() {
        LinkedHashMap<String, Object> param = Maps.newLinkedHashMap();

        Set<String> allFieldsName = UtilsDataReflection.getAllFieldsName(this.getEntityClazz());

        return this.mapper.selectPropsByMap(param, allFieldsName);
    }

    /**
     * 根据AccountId获取角色列表
     */
    public List<SysRole> queryByAccountId(String accountId) {
        List<SysRoleAccount> query = roleAccountService.query(ConstantKey.DEFAULT_ORDER_BY, new SysRoleAccount().setAccountId(accountId));
        if (CollectionUtils.isNotEmpty(query)) {
            List<String> roleIds = query.stream().map(SysRoleAccount::getRoleId).collect(Collectors.toList());
            Example example = new Example(SysRole.class);
            example.createCriteria().andIn("id", roleIds);
            return this.mapper.selectByExample(example);
        }
        return Lists.newArrayList();
    }

    public SysRole save(SysRole entity) {
        SysRole exists = super.getOne(new SysRole().setCode(entity.getCode()));

        if(ObjectUtil.isNotNull(exists) && !exists.getId().equalsIgnoreCase(entity.getId())) throw new BizException("角色编码已存在");

        return super.save(entity);
    }

    public void saveAndBinding(SysRole entity) {
        this.save(entity);

        List<SysResource> resources = entity.getResources();
        if (CollectionUtils.isEmpty(resources)) {
            throw new BizException(901, "未找到授权的资源信息，不能保存");
        }

        //删除旧关系
        SysRoleResource roleResource = new SysRoleResource();
        roleResource.setRoleId(entity.getId());
        List<SysRoleResource> list = roleResourceService.query(ConstantKey.DEFAULT_ORDER_BY, roleResource);
        if (CollectionUtils.isNotEmpty(list)) {
            roleResourceService.dropById(list.stream().map(item -> item.getId()).collect(Collectors.joining(",")));
        }

        //生成新关系
        resources.stream().forEach(item -> {
            roleResourceService.save(new SysRoleResource().setRoleId(entity.getId()).setResourceId(item.getId()));
        });

        Example example = new Example(SysRole.class);
        example.createCriteria().andLike("parentPath", "%" + entity.getParentPath() + "%").andEqualTo("delFlag", "0").andEqualTo("state", "1");
        //查询出我所有的下级
        List<SysRole> children = mapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(children)) {
            List<String> resIds = resources.stream().map(res -> res.getId()).collect(Collectors.toList());
            children.stream().forEach(role -> {
                //查询该孩子所有的关联资源
                SysRoleResource childRoleRes = new SysRoleResource();
                childRoleRes.setRoleId(role.getId());
                //获取我存在的所有关系
                List<SysRoleResource> exist = roleResourceService.query(ConstantKey.DEFAULT_ORDER_BY, childRoleRes);
                //把父类里面没有的删除掉
                if (CollectionUtils.isNotEmpty(exist)) {
                    List<SysRoleResource> result = exist.stream().filter(item -> resIds.contains(item.getResourceId())).collect(Collectors.toList());
                    //删除子类旧关系
                    roleResourceService.dropById(exist.stream().map(item -> item.getId()).collect(Collectors.joining(",")));
                    //生成新关系
                    roleResourceService.insertList(result);
                }
            });
        }
    }

    @Override
    public SysRole get(String id) {
        SysRole sysRole = super.get(id);

        SysRoleResource roleResource = new SysRoleResource();
        roleResource.setRoleId(sysRole.getId());
        List<SysRoleResource> list = roleResourceService.query(ConstantKey.DEFAULT_ORDER_BY, roleResource);

        if (CollectionUtils.isNotEmpty(list)) {
            List<String> resourceIds = list.stream().map(SysRoleResource::getResourceId).collect(Collectors.toList());

            Example example = new Example(SysResource.class);
            example.createCriteria().andEqualTo("delFlag", "0").andIn("id", resourceIds);
            sysRole.setResources(sysResourceService.queryByExample(ConstantKey.DEFAULT_ORDER_BY, example));
        }

        return sysRole;
    }

    public List<SysRole> queryRoleByAccountIds(List<String> accountIds) {
        return null;
    }
}
